#ifndef RenderingThread_H
#define RenderingThread_H

#include <QMutex>
#include <QSize>
#include <QThread>
#include <QWaitCondition>
#include <QImage>

// --GLOBALS

// size of the matrix for the median filter
const int cFilterMatrixSize = 3*3;
// convenient type for the median filter
typedef int TFilterMatrix[cFilterMatrixSize];
// pointer for a function that can derives the color index based on those three variables
typedef double (*TColorCalc)(int iter, double zx, double zy);

int median(TFilterMatrix p);

// different functions for color derivation
double fromIteration(int iter, double zx, double zy);
double fromRealPart(int iter, double zx, double zy);
double fromImaginaryPart(int iter, double zx, double zy);
double fromSum(int iter, double zx, double zy);
double fromAngle(int iter, double zx, double zy);
double fromNICA(int iter, double zx, double zy);

// convenient abstract class that can assign color
// this is for the mix of palettes and color indexing functions
class Renderer : public QObject
	{
		Q_OBJECT
	public:
		virtual QRgb render(int iter, double zx, double zy) =0;
	};

// rendering parameters that influence the resulting image
typedef struct {
	double centerx;
	double centery;
	QSize size;
	double scale;
	int maxiter;
	bool antialiasing;
	Renderer* renderer;
} TRenderParams;

// rendering thread definition
class RenderingThread : public QThread
	{
		Q_OBJECT
		
	public:
		RenderingThread(QObject *parent = 0);
		~RenderingThread();
		
		// restart threads to recompute image using new set of rendering parameters
		void render(const TRenderParams &renderParams);
		
	signals:
		void renderedImage(const QImage &image, const TRenderParams &renderParam);
		
	protected:
		void run();
		
	private:
		// computes Mandelbrot Set using the escape algorithm
		// more information: http://en.wikipedia.org/wiki/Mandelbrot_set
		inline QImage renderMandelbrotSet(const TRenderParams &renderParam);
		inline QImage medianFilter(const QImage *original);
		
		bool restarted() const;
		bool aborted() const;
		
		void setRestart(bool restart);
		void setAbort(bool abort);
		
		// this lock is for all instance members
		QMutex mutex;
		QWaitCondition condition;
		
		TRenderParams renderParams;		
		
		bool mRestart;
		bool mAbort;
	};


#endif